import { Directive, DirectiveBinding } from 'vue'

/**
 * @ClassName draggable
 * @Description 拖拽指令，使用：v-draggable
 * @Author xuyizhuo
 * @Date 2024/12/15 22:45
 * @example <MyComponent v-draggable>123</MyComponent>
 */
const draggable: Directive = {
    /**
     * @param {HTMLElement} el 绑定指令的元素
     * @param {DirectiveBinding} binding 绑定的参数
     */
    mounted(el: HTMLElement, binding: DirectiveBinding) {
        //console.log('binding', binding)

        const parentElement = el.parentElement // 获取父节点
        let controllerElement: string | undefined
        let move:
            | string
            | ((
                  event: MouseEvent,
                  position: {
                      x: number
                      y: number
                  },
                  el: HTMLElement,
              ) => void)
            | undefined
        if (typeof binding.value === 'string') {
            controllerElement = binding.value
        } else if (typeof binding.value === 'function') {
            move = binding.value
        } else if (binding.value) {
            controllerElement = binding.value.self
            move = binding.value.move
        }

        // 设置元素使用相对定位
        if (controllerElement === 'father' && parentElement) {
            parentElement.style.position = 'absolute'
        } else {
            el.style.position = 'absolute'
        }
        el.style.cursor = 'move' // 鼠标移动到元素上，显示为移动样式

        el.onmousedown = function (e) {
            let disX = e.pageX - el.offsetLeft
            let disY = e.pageY - el.offsetTop

            if (controllerElement === 'father') {
                disX = e.pageX - (parentElement?.offsetLeft || 0)
                disY = e.pageY - (parentElement?.offsetTop || 0)
            } else {
                disX = e.pageX - el.offsetLeft
                disY = e.pageY - el.offsetTop
            }
            document.onmousemove = function (e) {
                if (typeof move === 'function') {
                    move(e, { x: disX, y: disY }, el)
                } else {
                    let x = e.pageX - disX
                    let y = e.pageY - disY
                    let maxX = 0
                    let maxY = 0

                    if (parentElement) {
                        if (controllerElement === 'father') {
                            maxX = (parentElement.parentElement?.offsetWidth || 0) - parentElement.offsetWidth
                            maxY = (parentElement.parentElement?.offsetHeight || 0) - parentElement.offsetHeight
                        } else {
                            maxX = parentElement.offsetWidth - el.offsetWidth
                            maxY = parentElement.offsetHeight - el.offsetHeight
                        }
                    }

                    // 限制拖拽范围
                    if (x < 0) {
                        x = 0
                    } else if (x > maxX) {
                        x = maxX
                    }

                    if (y < 0) {
                        y = 0
                    } else if (y > maxY) {
                        y = maxY
                    }

                    if (controllerElement === 'father' && parentElement) {
                        parentElement.style.left = x + 'px'
                        parentElement.style.top = y + 'px'
                        parentElement.style.right = 'unset'
                        parentElement.style.bottom = 'unset'
                    } else {
                        el.style.left = x + 'px'
                        el.style.top = y + 'px'
                        el.style.right = 'unset'
                        el.style.bottom = 'unset'
                    }
                }
            }
            document.onmouseup = function () {
                document.onmousemove = document.onmouseup = null
            }
        }
    },

    // unmounted(el) {
    //     el.removeEventListener('mousedown', handleMouseDown)
    // },
}

export default draggable
